package networking;

import gameStates.absGamesStates.AbsIngameState;
import gameStates.absGamesStates.network.AbsNetworkState;

import java.util.concurrent.Callable;

import logic.common.player.Player;
import logic.ships.hunter.Hunter;
import logic.ships.moveableShip.MovableShip;
import logic.weapons.projectileWeapons.heatSeeker.HeatSeeker;

import com.captiveimagination.jgn.JGN;
import com.captiveimagination.jgn.synchronization.SyncObjectManager;
import com.captiveimagination.jgn.synchronization.message.SynchronizeRemoveMessage;
import com.jme.util.GameTaskQueueManager;

public abstract class SyncManager implements SyncObjectManager {
	
	public static final int UDPPORT = 9140;
	public static final int TCPPORT = 9140;
	
	protected SynchronizationManager graphicSyncManager;
	protected GraphicSyncController graphicController;
	
	protected AbsIngameState ingameState;
	protected AbsNetworkState networkState;
	
	public SyncManager(AbsNetworkState networkState) {
		this.networkState = networkState;
		
		ingameState = networkState.getIngameState();
		
		assert(networkState != null);
	}
	
	protected void initSyncManager() {
		if(ingameState != null) {
			graphicController = new GraphicSyncController();
			
			graphicSyncManager = getNewSyncManager();
			graphicSyncManager.addSyncObjectManager(this);
			JGN.createThread(graphicSyncManager).start();
		}
	}
	
	protected abstract SynchronizationManager getNewSyncManager();
	
	@Override
	public boolean remove(SynchronizeRemoveMessage srm, Object obj) {
		if(obj instanceof MovableShip) {
			final MovableShip ship = (MovableShip)obj;
			if(!(ship instanceof Hunter)) networkState.unregisterObject(ship);
			GameTaskQueueManager.getManager().update(new Callable<Void>() {
				@Override
				public Void call() throws Exception {
					ship.destroy();
					return null;
				}
			});
			
			return true;
		} else if(obj instanceof HeatSeeker) {
			final HeatSeeker hs = (HeatSeeker)obj;
			networkState.unregisterObject(hs);
			GameTaskQueueManager.getManager().update(new Callable<Void>() {
				@Override
				public Void call() throws Exception {
					hs.destroy();
					return null;
				}
			});
			
			return true;
		}
		
		return false;
	}
	
	protected void putPlayerToHunter(Hunter hunter, int playerID) {
		Player player = networkState.getPlayer(playerID);
		assert(player != null);
		
		player.changeHunter(hunter, true);
	}
	
	public SynchronizationManager getSyncManager() { return graphicSyncManager; }
	
	public GraphicSyncController getGraphicSyncController() { return graphicController; }
	
	public void cleanup() {
		ingameState = null;
		graphicSyncManager.cleanup();
	}
}